package com.fuyun.rpc.server.annotations;

import com.fuyun.rpc.common.domain.ServiceMetaInfo;
import com.fuyun.rpc.server.RpcApplication;
import com.fuyun.rpc.server.config.RpcConfig;
import com.fuyun.rpc.server.registry.LocalRegistry;
import com.fuyun.rpc.server.registry.Registry;
import com.fuyun.rpc.server.registry.RegistryFactory;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.SpringApplication;
import org.springframework.lang.NonNull;

/**
 * RpcProviderBootstrap 类负责在Bean初始化后，对带有FuyunRpcService注解的Bean进行处理 主要功能是将这些Bean注册为RPC服务
 *
 * @author: zrq1351
 * @date: 2025/2/18
 */
@Slf4j
@AllArgsConstructor
public class RpcProviderBootstrap implements BeanPostProcessor {

	private RpcApplication rpcApplication;

	/**
	 * 在Bean初始化后进行后处理 此方法主要用于处理带有FuyunRpcService注解的Bean，对其进行服务注册
	 *
	 * @param bean     初始化后的Bean实例
	 * @param beanName Bean的名称
	 * @return 处理后的Bean实例
	 * @throws BeansException 如果处理过程中发生异常
	 */
	@Override
	public Object postProcessAfterInitialization(Object bean, @NonNull String beanName) throws BeansException {
		Class<?> beanClass = bean.getClass();
		FuyunRpcService rpcService = beanClass.getAnnotation(FuyunRpcService.class);
		Class<?> startupClass = new SpringApplication().getMainApplicationClass();
		EnableFuyunServerRpc annotation = startupClass.getAnnotation(EnableFuyunServerRpc.class);
		if (rpcService != null && annotation != null) {
			// 需要注册服务
			// 1. 获取服务基本信息
			Class<?> interfaceClass = rpcService.value();
			// 默认值处理
			if (interfaceClass == void.class) {
				interfaceClass = beanClass.getInterfaces()[0];
			}
			String serviceName = interfaceClass.getName();
			String serviceVersion = rpcService.serviceVersion();
			String group = rpcService.group();
			if (StringUtils.isBlank(serviceVersion)) {
				serviceVersion = rpcApplication.getRegistryConfig().getServiceVersion();
			}
			if (StringUtils.isBlank(group)) {
				group = rpcApplication.getRegistryConfig().getGroup();
			}
			// 2. 注册服务
			// 本地注册
			LocalRegistry.register(serviceName, beanClass);

			final RpcConfig rpcConfig = rpcApplication.getRpcConfig();
			Registry registry = RegistryFactory.getInstance(rpcConfig.getRegistry());
			ServiceMetaInfo serviceMetaInfo = new ServiceMetaInfo();
			serviceMetaInfo.setServiceName(serviceName);
			serviceMetaInfo.setServiceVersion(serviceVersion);
			serviceMetaInfo.setServiceGroup(group);
			serviceMetaInfo.setServiceHost(rpcConfig.getServerHost());
			serviceMetaInfo.setServicePort(rpcConfig.getServerPort());
			try {
				registry.register(serviceMetaInfo);
			} catch (Exception e) {
				throw new RuntimeException(serviceName + " 服务注册失败", e);
			}
		}

		return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
	}
}